package nl.infodation.emr.pricingservice.controller;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import nl.infodation.emr.pricingservice.data.UserSearchItem;
import nl.infodation.emr.pricingservice.entity.User;
import nl.infodation.emr.utility.StringUtil;

import com.vaadin.data.util.BeanItem;

@SuppressWarnings({"deprecation", "rawtypes"})
public class UserController extends
		AbstractBaseController<User, UserSearchItem, String> {
	
	@Override
	public long getTotalNumberItemByCriteria(UserSearchItem t) {
		long countResult = 0l;
		EntityManager entityManager = null;
		try {
			entityManager = EM_FACTORY.createEntityManager();
			entityManager.getTransaction().begin();
			queryString.setLength(0);
			final UserSearchItem item = t;

			// Process for role
			final User p = new User();
			if (!StringUtil.isEmptyOrBlank(item.getUsername())) {
				p.setUsername(item.getUsername());
			}
			buildSelectCount(p);
			buildQueryAndParams(p);
			buildQueryWithBoolean(t);
			buildQueryWithObject(t);
			
			final TypedQuery<Long> query = entityManager.createQuery(
					queryString.toString(), Long.class);
			LOG.info("Executing the query \"{}\".", queryString);
			countResult = query.getSingleResult();

			entityManager.getTransaction().commit();

		} catch (IllegalStateException | IllegalAccessException ex) {
			LOG.error("Error reading getTotalNumberItemByCriteria", ex);
			if (entityManager != null
					&& entityManager.getTransaction().isActive()) {
				LOG.info("Rolling back...");
				entityManager.getTransaction().rollback();
			}
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}
		return countResult;
	}

	@Override
	public List<BeanItem> getPaginationByCriteria(UserSearchItem object,
			int startPage, int pageSize) {
		final List<BeanItem> beans = new ArrayList<BeanItem>();
		EntityManager entityManager = null;
		try {
			entityManager = EM_FACTORY.createEntityManager();
			entityManager.getTransaction().begin();
			queryString.setLength(0);
			final User u = new User();
			if (null != object.getUsername()) {
				u.setUsername(object.getUsername());
			}

			buildSelect(u);
			buildQueryAndParams(u);
			buildQueryWithBoolean(object);
			buildQueryWithObject(object);

			final TypedQuery<User> query = entityManager.createQuery(
					queryString.toString(), User.class);
			if (startPage > 0) {
				query.setFirstResult((startPage - 1) * pageSize);
			} else {
				query.setFirstResult(1);
			}
			query.setMaxResults(pageSize);
			LOG.info("Executing the query \"{}\".", queryString);
			final List<User> results = query.getResultList();
			if (!results.isEmpty()) {
				for (User user : results) {
					beans.add(new BeanItem<User>(user));
				}
			}
			entityManager.getTransaction().commit();

		} catch (IllegalStateException | IllegalAccessException ex) {
			LOG.error("Error reading getPaginationByCriteria.", ex);
			if (entityManager != null
					&& entityManager.getTransaction().isActive()) {
				LOG.info("Rolling back...");
				entityManager.getTransaction().rollback();
			}
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}
		return beans;
	}

	private void buildQueryWithObject(UserSearchItem object) {
		if (null != object.getRoleName()) {
			if (!queryString.toString().toLowerCase().contains("where")) {
				append(" WHERE ");
				append(queryObjChar + "role.roleName" + "  = '"
						+ object.getRoleName().toString() + "'");
			} else {
				append(" AND ");
				append(queryObjChar + "role.roleName" + "  = '"
						+ object.getRoleName().toString() + "'");
			}
		}
	}

	private void buildQueryWithBoolean(UserSearchItem object) {
		if (null != object.getSuperAdmin()) {
			if (!queryString.toString().toLowerCase().contains("where")) {
				append(" WHERE ");
				append(queryObjChar + "superAdmin" + "  = '"
						+ object.getSuperAdmin().toString() + "'");
			} else {
				append(" AND ");
				append(queryObjChar + "superAdmin" + "  = '"
						+ object.getSuperAdmin().toString() + "'");
			}
		}

		if (null != object.getNormalAdmin()) {
			if (!queryString.toString().toLowerCase().contains("where")) {
				append(" WHERE ");
				append(queryObjChar + "normalAdmin" + "  = '"
						+ object.getNormalAdmin().toString() + "'");
			} else {
				append(" AND ");
				append(queryObjChar + "normalAdmin" + "  = '"
						+ object.getNormalAdmin().toString() + "'");
			}
		}
		
		if (null != object.getActive()) {
			if (!queryString.toString().toLowerCase().contains("where")) {
				append(" WHERE ");
				append(queryObjChar + "isActive" + "  = "
						+ object.getActive().toString());
			} else {
				append(" AND ");
				append(queryObjChar + "isActive" + "  = "
						+ object.getActive());
			}
		}
	}

	@Override
	public List<BeanItem> getPaginationList(int startPage, int pageSize) {
		return getPaginationByCriteria(new UserSearchItem(), startPage,
				pageSize);
	}

	@Override
	public long getTotalNumberItem() {
		return getTotalNumberItemByCriteria(new UserSearchItem());
	}

	@Override
	protected Boolean isObject(Field field) {
		if (field.getName().equals("role"))
			return Boolean.TRUE;
		return Boolean.FALSE;
	}

	@Override
	protected User buildCriteria(UserSearchItem search) {
		final User p = new User();
		if (!StringUtil.isEmptyOrBlank(search.getUsername())) {
			p.setUsername(search.getUsername());
		}
		return p;
	}
	
	

}
